home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / Developer Essentials Jul 90 / DTS Sample Code / Apple II Sample Code / MPW IIGS SC / SC.020.DTS.Tools.Libs / ptrcheck.aii < prev    next >
Encoding:
Text File  |  1990-06-25  |  7.5 KB  |  386 lines  |  [TEXT/MPS ]

  1. ******************************************************************************
  2. *
  3. * local pointer checker -- Version 3.0
  4. *
  5. * Copyright (C) 1989-1990 by Apple Computer.
  6. * Written by Eric Soldan.
  7. *
  8. * Developer Technical Support Apple II Sample Code
  9. *
  10. ******************************************************************************
  11.  
  12.         case    on
  13.  
  14. rtlStkDepth    equ    50        ;You may need to make this bigger.
  15.  
  16. ******************************************************************************
  17.  
  18. * These functions are to help detect usage of C pointers and handles that are
  19. * not initialized.  In main(), call initPtrCheck().  Do NOT call other
  20. * functions in main.
  21. * In other functions, call zapLocals() as the first thing in the function.
  22. * checkForHit() will automatically be called whenever you exit a function.
  23. * You can call checkForHit() at any point you want, also.  If you have an idea
  24. * of which function has a pointer problem, but you are not sure where in
  25. * the function the problem is, you can add some calls to checkForHit().
  26. * The functions initPtrCheck(), closePtrCheck(), zapLocals(), and
  27. * checkForHit() can be conditionally set active or inactive with #define
  28. * statements.  This way they can be active when developing, and turned off
  29. * when making a production version.  The calls can be defined to nothing,
  30. * thus making any reference to them drop out of the object code.
  31. *
  32. * So, a C program would use the functions as below:
  33. *
  34. * main()
  35. * {
  36. *     initPtrCheck(_ownerid);
  37. *     /* Your code goes here */
  38. *     closePtrCheck();
  39. *     exit(0);
  40. * }
  41. *
  42. * void           someFnCalledByMain(parm1, parm2)
  43. * unsigned int   parm1, parm2;
  44. * {
  45. *     unsigned int   i, j, k;
  46. *     unsigned long  theID;
  47. *
  48. *     zapLocals();
  49. *     /* Your code goes here */
  50. *     checkForHit();
  51. * }
  52.  
  53. * Note that zapLocals() needs to be the first code in a function.  Also,
  54. * you can't call zapLocals before you call initPtrCheck().  Given this
  55. * dependency, you can't call zapLocals in main().  To fix this problem,
  56. * you may wish to have a nearly empty main().  You may want it to just
  57. * do the initPtrCheck() and closePtrCheck(), and the code in between
  58. * simply calls something like main0(), which can have a zapLocals().
  59.  
  60. ******************
  61.  
  62. * The return address to exit zapLocals is used to point to the code used to
  63. * create the stack frame.  The stack frame code should look like the below.
  64. * The values in front are the negative offsets from the return address.
  65. * (This is why zapLocals() must be the first code in a function.)
  66.  
  67. * E        PHD      
  68. * D        TSC      
  69. * C        SEC      
  70. * BA9        SBC      #$fb
  71. * 8        TCD      
  72. * 765        ADC      #$f0
  73. * 4        TCS      
  74.  
  75. * 321.0        JSL      >zapLocals
  76.  
  77. ******************************************************************************
  78.  
  79.         include    'm16.memory'
  80.         include    'm16.misctool'
  81.         include    'm16.util2'
  82.  
  83.  
  84.         export    initPtrCheck
  85. initPtrCheck    proc
  86.         export    ptrCheckHndl, rtlStkPtr, rtlStk, zapval
  87.  
  88.         DefineStack
  89.  
  90. hndl        long            ;Must be at 1,s.
  91. ptr        long
  92.  
  93. dpage        word
  94. retaddr        block    3
  95.  
  96. userid        word
  97.  
  98.         phd
  99.  
  100.         pha            ;Make space for locals.
  101.         pha
  102.         pha
  103.         pha
  104.         tsc
  105.         tcd
  106.  
  107.         pea    1        ;Get the bank-sized handle.
  108.         lda    #0
  109.         sta    >rtlStkPtr    ;Nothing on "stack" yet.
  110.         pha
  111.         pei    userid
  112.         pea    $C010
  113.         pha
  114.         pha
  115.         _NewHandle
  116.         bcc    @gothndl
  117.  
  118.         lda    #0
  119.         sta    >ptrCheckHndl    ;Flag as no handle.
  120.         sta    >ptrCheckHndl+2
  121.         sta    >zapval        ;"Pattern" is 0.
  122.         sta    >$0        ;Point 0-2 to the screen.
  123.         lda    #$E100        ;If there is any bad stuff
  124.         sta    >$1        ;going on, then it will show
  125.         bra    @exit        ;on the super-hi-res screen.
  126.                     ;This is true only for handles.
  127.                     ;Simple pointers will still
  128.                     ;store into zpage.  Storing
  129.                     ;into zpage will, most likely,
  130.                     ;cause the system to die.
  131.                     ;The best test is when the
  132.                     ;system has enough memory to
  133.                     ;create the 64k hit-test handle.
  134.  
  135. @gothndl        lda    hndl        ;Keep the handle, and initialize it.
  136.         sta    >ptrCheckHndl
  137.         lda    hndl+2
  138.         sta    >ptrCheckHndl+2
  139.  
  140.         ldy    #2        ;Dereference the handle to get to
  141.         lda    [hndl],y        ;the bank of memory.
  142.         sta    ptr+2
  143.         lda    [hndl]
  144.         sta    ptr
  145.         lda    ptr+2        ;Move byte 2 of bank address into
  146.         xba            ;byte 3 also.
  147.         ora    ptr+2
  148.         sta    >zapval
  149.  
  150.         ldy    #0        ;Fill the handle with the bank value,
  151. @loop        sta    [ptr],y        ;so pointers within the handle end
  152.         iny            ;up pointing back into the handle.
  153.         iny
  154.         bne    @loop
  155.  
  156.         sta    >$0
  157.         sta    >$2
  158.  
  159. @exit        pla
  160.         pla
  161.         pla
  162.         pla
  163.  
  164.         pld
  165.         rtl
  166.  
  167. ptrCheckHndl    dc.l    0
  168. zapval        dc.w    0
  169. rtlStkPtr    dc.w    0
  170. rtlStk        ds.b    rtlStkDepth*3
  171.  
  172.         endp
  173.  
  174. ******************
  175.  
  176.         export    zapLocals
  177. zapLocals    proc
  178.         export    saveRegs, getRegs
  179.         import    zapval, rtlStkPtr, rtlStk, checkForHitz
  180.  
  181.         DefineStack
  182.  
  183. ptr        long
  184.  
  185. dpage        word
  186. retaddr        block    3
  187.  
  188.         phd
  189.  
  190.         pha            ;Make space for locals.
  191.         pha
  192.         tsc
  193.         tcd
  194.  
  195.         lda    retaddr+1    ;Use return address as pointer.
  196.         sta    ptr+1
  197.         lda    retaddr
  198.         sec
  199.         sbc    #$0A
  200.         sta    ptr
  201.         lda    [ptr]        ;sbc value
  202.         tax
  203.         ldy    #4
  204.         lda    [ptr],y        ;adc value
  205.  
  206.         sta    ptr
  207.         txa
  208.         sec
  209.         sbc    ptr
  210.         beq    @exit        ;No stack frame at all.
  211.         tax            ;Save this to fetch RTL address.
  212.         tay            ;Number of bytes to zap.
  213.         dey
  214.         beq    @exit        ;Just in case.
  215.  
  216.         tsc
  217.         clc
  218.         adc    #retaddr+2    ;Point to beginning of stack
  219.         sta    ptr        ;frame to clobber.
  220.         stz    ptr+2
  221.  
  222.         shortm
  223.         lda    >zapval        ;Pattern to clobber with.
  224. @loop        sta    [ptr],y
  225.         dey
  226.         bne    @loop
  227.         longm
  228.  
  229.         inx            ;Save the return address on rtlStk.
  230.         inx
  231.         txy            ;yreg is offset to return address.
  232.         lda    >rtlStkPtr
  233.         cmp    #rtlStkDepth*3    ;Make sure we aren't overflowing rtlStk.
  234.         bcc    @a
  235.         brk    #$AA
  236.  
  237. @a        tax
  238.         lda    [ptr],y
  239.         sta    >rtlStk,x
  240.         iny
  241.         inx
  242.         lda    [ptr],y
  243.         sta    >rtlStk,x    ;Return address now on rtlStk.
  244.         inx
  245.         inx
  246.         txa
  247.         sta    >rtlStkPtr    ;Save new index into rtlStk.
  248.  
  249.         lda    #rtlCheck>>8    ;Put return address of checking
  250.         sta    [ptr],y        ;routine in place of regular
  251.         dey            ;return address.
  252.         lda    #rtlCheck-1
  253.         sta    [ptr],y
  254.  
  255. @exit        pla
  256.         pla
  257.  
  258.         pld
  259.         rtl
  260.  
  261. rtlCheck        equ    *        ;This is where we end up when a c
  262.                     ;function exits with an rtl.
  263.         jsl    saveRegs        ;Keep registers for return value for c.
  264.  
  265.         lda    >rtlStkPtr    ;Get the real return address onto the stack.
  266.         tax
  267.         dex
  268.         dex
  269.         lda    >rtlStk,x
  270.         pha            ;We pushed middle and hi byte here.
  271.         phb
  272.         pla            ;We just pulled the middle byte.
  273.         dex
  274.         lda    >rtlStk,x
  275.         pha            ;We pushed low and middle byte here, so
  276.                     ;we have a full rtl address on stack.
  277.         txa
  278.         sta    >rtlStkPtr
  279.         jml    checkForHitz
  280.  
  281. saveRegs        sta    >keepa        ;Keep everything.
  282.         txa
  283.         sta    >keepx
  284.         tya
  285.         sta    >keepy
  286.         php
  287.         php
  288.         pla
  289.         sta    >keepp
  290.         rtl
  291.  
  292. getRegs        lda    >keepp
  293.         pha
  294.         lda    >keepx
  295.         tax
  296.         lda    >keepy
  297.         tay
  298.         lda    >keepa
  299.         plp
  300.         plp
  301.         rtl
  302.  
  303. keepa        dc.w    0
  304. keepx        dc.w    0
  305. keepy        dc.w    0
  306. keepp        dc.w    0
  307.  
  308.         endp
  309.  
  310. ******************
  311.  
  312.         export    checkForHit
  313. checkForHit    proc
  314.         export    checkForHitz
  315.         import    zapval, saveRegs, getRegs
  316.  
  317.         jsl    saveRegs
  318.  
  319. checkForHitz    lda    >zapval
  320.         beq    @exit        ;When using zpage as hit
  321.                     ;detector, there is nothing
  322.                     ;we can check.  We just have
  323.                     ;to wait until the system
  324.                     ;dies a horrible death.  This
  325.                     ;horrible death should happen
  326.                     ;faster when clobbering zpage.
  327.         tax
  328.         and    #$FFFE        ;So we can go by words.
  329.         tay
  330.         txa
  331.  
  332.         phb
  333.         pha
  334.         plb
  335.         plb
  336.  
  337. @loop        cmp    |$0,y
  338.         bne    @oops
  339.         iny
  340.         iny
  341.         bne    @loop
  342.  
  343.         plb            ;Put data bank back.
  344. @exit        jml    getRegs
  345.  
  346. @oops        plb
  347.  
  348.         brk    #$AB        ;Bank is indicated by acc.
  349.                     ;Offset into bank that was hit is
  350.                     ;in the yreg.
  351.                     ;The program can be resumed, but unless
  352.                     ;the hit is repaired, the program will
  353.                     ;break again.
  354.  
  355.         jml    getRegs        ;Allow option of continuing from debugger.
  356.  
  357.         endp
  358.  
  359. ******************
  360.  
  361.         export    closePtrCheck
  362. closePtrCheck    proc
  363.         import    ptrCheckHndl, zapval
  364.  
  365.         jsl    checkForHit    ;Let's make sure there were no hits.
  366.  
  367.         lda    >zapval
  368.         beq    @exit        ;No handle to dispose of.
  369.  
  370.         lda    >ptrCheckHndl+2
  371.         pha
  372.         lda    >ptrCheckHndl
  373.         pha
  374.         _DisposeHandle        ;We got rid of what we created.
  375.  
  376.         lda    #0
  377.         sta    >zapval
  378.  
  379. @exit        rtl
  380.  
  381.         endp
  382.  
  383.         END
  384.  
  385.